package sfin.service;

import java.util.Calendar;
import java.util.Map;
import java.util.ResourceBundle;

import sfin.swt.data.DateData;
import sfin.swt.util.FormatterUtil;
import br.com.statizo.financeiro.core.repository.impl.ColorConfigRepository;
import br.com.statizo.financeiro.core.repository.impl.ConfiguracoesRepositorio;
import br.com.statizo.financeiro.domain.entity.impl.ColorConfig;
import br.com.statizo.financeiro.domain.entity.impl.Configuracoes;
import br.com.statizo.financeiro.domain.enums.ColorConfigType;
import br.com.statizo.financeiro.domain.enums.DateConfigType;

public class ConfigService extends AbstractService{

	private ColorConfigRepository colorRepo;
	private ConfiguracoesRepositorio configRepo;
	
	
	public Map<ColorConfigType,ColorConfig> colors;

	private ColorConfig[] bgColors = new ColorConfig[18];
	private Configuracoes configuracoes;

	private DateConfigType[] dtPgtoTypes = new DateConfigType[3];
	
	private PeriodoService periodoService;
	
	public ConfigService(ResourceBundle bundle, FormatterUtil formatterUtil, ColorConfigRepository colorRepo, 
			ConfiguracoesRepositorio configRepo, PeriodoService periodoService) {
		super(bundle, formatterUtil);
		this.colorRepo = colorRepo;
		this.configRepo = configRepo;
		this.periodoService = periodoService;
		initializeConfigs();
		initializeBackColors();
		initializeDtPgtoTypes();
	}
	
	

	private void initializeDtPgtoTypes() {
		dtPgtoTypes[0] = DateConfigType.DT_PGTO_ATUAL;
		dtPgtoTypes[1] = DateConfigType.DT_PGTO_PRI_DIA_MES_ANALISADO;
		dtPgtoTypes[2] = DateConfigType.DT_PGTO_PRIM_DIA_MES_CORRENTE;
	}

	private void initializeConfigs() {
		configuracoes = configRepo.getConfiguracoes();
		if(configuracoes == null){
			configRepo.entityManagerRefresh();
			configRepo.beginTransaction();
			configuracoes = configRepo.merge(new Configuracoes());
			configRepo.commit();
		}
	}

	private void initializeBackColors(){
		bgColors[0] = getPersistedInstance(ColorConfigType.RECEITA_PG_BG);
		bgColors[1] = getPersistedInstance(ColorConfigType.RECEITA_PG_FG);
		
		bgColors[2] = getPersistedInstance(ColorConfigType.RECEITA_NPG_BG);
		bgColors[3] = getPersistedInstance(ColorConfigType.RECEITA_NPG_FG);		
		
		bgColors[4] = getPersistedInstance(ColorConfigType.RECEITA_AGE_BG);
		bgColors[5] = getPersistedInstance(ColorConfigType.RECEITA_AGE_FG);
		
		bgColors[6] = getPersistedInstance(ColorConfigType.DESPESA_PG_BG);
		bgColors[7] = getPersistedInstance(ColorConfigType.DESPESA_PG_FG);
		
		bgColors[8] = getPersistedInstance(ColorConfigType.DESPESA_NPG_BG);
		bgColors[9] = getPersistedInstance(ColorConfigType.DESPESA_NPG_FG);
		
		bgColors[10] = getPersistedInstance(ColorConfigType.DESPESA_AGE_BG);
		bgColors[11] = getPersistedInstance(ColorConfigType.DESPESA_AGE_FG);
		
		bgColors[12] = getPersistedInstance(ColorConfigType.INVEST_PG_BG);
		bgColors[13] = getPersistedInstance(ColorConfigType.INVEST_PG_FG);
		
		bgColors[14] = getPersistedInstance(ColorConfigType.INVEST_NPG_BG);
		bgColors[15] = getPersistedInstance(ColorConfigType.INVEST_NPG_FG);
		
		bgColors[16] = getPersistedInstance(ColorConfigType.INVEST_AGE_BG);
		bgColors[17] = getPersistedInstance(ColorConfigType.INVEST_AGE_FG);
	}
	
	private boolean backPersisted(){
		return colorRepo.count() > 0;
	}
	
	private ColorConfig getPersistedInstance(ColorConfigType id){
		ColorConfig color = colorRepo.getById(id);
		if(color != null)
			return color;	
		return new ColorConfig(id);
	}
	
	
	public void updateConfigs(boolean initContaPadrao, int dtPgtoIndex){
		configRepo.entityManagerRefresh();
		configRepo.beginTransaction();
		configuracoes.setIniciarContaPadrao(initContaPadrao);
		configuracoes.setDtPgtoDefault(DateConfigType.values()[dtPgtoIndex]);
		configuracoes = configRepo.merge(configuracoes);
		configRepo.commit();
	}
	
	public void updateBackColors(int[][][] backRgbs){
		if(backRgbs == null || backRgbs.length != bgColors.length)
			throw new IllegalArgumentException("backRgbs size is invalid.");

		colorRepo.entityManagerRefresh();
		colorRepo.beginTransaction();

		try{
			for (int i = 0; i < backRgbs.length; i++) {
				bgColors[i].setBackground(backRgbs[i][0]);
				bgColors[i] = colorRepo.merge(bgColors[i]);
			}
			colorRepo.commit();
			notifyListeners();
		}catch(Exception e){
			colorRepo.rollBack();
		}
	}

	public int[][][] getBackColors(){
		int[][][] backColors = new int[bgColors.length][2][3];
		for (int i = 0; i < bgColors.length; i++) {
			
			if(backPersisted()){
				backColors[i][0] = bgColors[i].getRGB();
			}else{
				backColors[i][0] = bgColors[i].getDefaultRGB();
			}

			backColors[i][1] = bgColors[i].getDefaultRGB();

		}
		return backColors;
	}

	public int[] getBackgroundColor(ColorConfigType type){
		for (int i = 0; i < bgColors.length; i++) {
			if(bgColors[i].getType() == type){
				
				if(backPersisted()){
					return bgColors[i].getRGB();	
				}else{
					return bgColors[i].getDefaultRGB();
				}
			}
		}
		return new int[]{255,255,255};
	}
	
	public boolean isInitContaPadrao(){
		return this.configuracoes.isIniciarContaPadrao();
	}
	
	public int getDtPgtoConfigOrdinal(){
		return configuracoes.getDtPgtoDefault().ordinal();
	}
	
	public DateConfigType[] getDtPgtoTypes() {
		return dtPgtoTypes;
	}
	
	public String[] getDtPgtoLabels(){
		String[] names = new String[dtPgtoTypes.length];
		for (int i = 0; i < dtPgtoTypes.length; i++) {
			names[i] = bundle.getString(dtPgtoTypes[i].getLabel());
		}
		return names;
	}
	
	public DateData getDefaultPgtoDate(){
		
		DateConfigType type = configuracoes.getDtPgtoDefault(); 
		
		if(DateConfigType.DT_PGTO_ATUAL.equals(type)){
			return new DateData().in(Calendar.getInstance());
		}else if(DateConfigType.DT_PGTO_PRI_DIA_MES_ANALISADO.equals(type)){
			return new DateData().inDay(1).inMonth(periodoService.getApplicationMonth()).inYear(periodoService.getApplicationYear());
		}else if(DateConfigType.DT_PGTO_PRIM_DIA_MES_CORRENTE.equals(type)){
			return new DateData().in(Calendar.getInstance()).inDay(1);
		}else{
			return new DateData().in(Calendar.getInstance());
		}
	}
	
	
}	
